#!/usr/bin/env bash
##############################################################################
##                                                                          ##
##  Grails JVM Bootstrap for UN*X                                           ##
##                                                                          ##
##############################################################################

PROGNAME=`basename "$0"`
DIRNAME=`dirname "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that
MAX_FD="maximum"

warn() {
    echo "${PROGNAME}: $*"
}

die() {
    warn "$*"
    exit 1
}

earlyInit() {
	return
}
lateInit() {
	return
}

GROOVY_STARTUP=~/.groovy/startup
if [ -r "$GROOVY_STARTUP" ]; then
	. "$GROOVY_STARTUP"
fi

earlyInit

# OS specific support (must be 'true' or 'false').
cygwin=false;
darwin=false;
mingw=false;
case "`uname`" in
    CYGWIN*)
        cygwin=true
        ;;

    Darwin*)
        darwin=true
        ;;

    MINGW*)
        mingw=true
        ;;
esac

# Attempt to set JAVA_HOME if it's not already set
if [ -z "$JAVA_HOME" ]; then

	# Set JAVA_HOME for Darwin
	if $darwin; then

		[ -z "$JAVA_HOME" -a -d "/Library/Java/Home" ] &&
			export JAVA_HOME="/Library/Java/Home"

		[ -z "$JAVA_HOME" -a -d "/System/Library/Frameworks/JavaVM.framework/Home" ] &&
			export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Home"

	fi

fi

# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
    [ -n "$GRAILS_HOME" ] &&
        GRAILS_HOME=`cygpath --unix "$GRAILS_HOME"`
    [ -n "$JAVACMD" ] &&
        JAVACMD=`cygpath --unix "$JAVACMD"`
    [ -n "$JAVA_HOME" ] &&
        JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
    [ -n "$CP" ] &&
        CP=`cygpath --path --unix "$CP"`
fi

# quick detection of JDK version without JVM startup overhead
CLASSFILE_HEADER_FILE="${JAVA_HOME}/include/classfile_constants.h"
if [ -z "$GRAILS_NO_PERMGEN" -a -f "${CLASSFILE_HEADER_FILE}" ]; then
  CLASSFILE_VERSION=`cat "${CLASSFILE_HEADER_FILE}" | grep "#define JVM_CLASSFILE_MAJOR_VERSION" | awk '{ print $3 }' 2> /dev/null`
  if [ 0$CLASSFILE_VERSION -ge 52 ]; then
    GRAILS_NO_PERMGEN=1
  fi 
fi

# Remove possible trailing slash (after possible cygwin correction)
GRAILS_HOME=`echo $GRAILS_HOME | sed -e 's|/$||g'`

# Locate GRAILS_HOME if not it is not set
if [ -z "$GRAILS_HOME" -o ! -d "$GRAILS_HOME" ] ; then
  # resolve links - $0 may be a link to groovy's home
  PRG="$0"

  # need this for relative symlinks
  while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
    PRG="$link"
    else
    PRG=`dirname "$PRG"`"/$link"
    fi
  done

  SAVED="`pwd`"
  cd "`dirname \"$PRG\"`/.."
  GRAILS_HOME="`pwd -P`"
  cd "$SAVED"
fi

# Warn the user if JAVA_HOME and/or GRAILS_HOME are not set.
if [ -z "$JAVA_HOME" ] ; then
    die "JAVA_HOME environment variable is not set"
elif [ ! -d "$JAVA_HOME" ] ; then
    die "JAVA_HOME is not a directory: $JAVA_HOME"
fi

if [ -z "$GRAILS_HOME" ] ; then
    warn "GRAILS_HOME environment variable is not set"
fi

if [ ! -d "$GRAILS_HOME" ] ; then
    die "GRAILS_HOME is not a directory: $GRAILS_HOME"
fi

# Use default groovy-conf config
if [ -z "$STARTER_CONF" ]; then
    STARTER_CONF="$GRAILS_HOME/conf/groovy-starter.conf"
fi
STARTER_CLASSPATH="wrapper/grails-wrapper-runtime-2.4.4.jar:wrapper:."

# Allow access to Cocoa classes on OS X
if $darwin; then
    STARTER_CLASSPATH="$STARTER_CLASSPATH:/System/Library/Java/Support"
fi

# Create the final classpath
# Setting a classpath using the -cp or -classpath option means not to use
# the global classpath. Groovy behaves then the same as the java
# interpreter
if [ -n "$CP" ] ; then
    CP="$CP"
elif [ -n "$CLASSPATH" ] ; then
    CP="$CLASSPATH"
fi

# Determine the Java command to use to start the JVM
if [ -z "$JAVACMD" ]; then
    if [ -n "$JAVA_HOME" ]; then
        if [ -x "$JAVA_HOME/jre/sh/java" ]; then
            # IBM's JDK on AIX uses strange locations for the executables
            JAVACMD="$JAVA_HOME/jre/sh/java"
        else
            JAVACMD="$JAVA_HOME/bin/java"
        fi
    else
        JAVACMD="java"
    fi
fi
if [ ! -x "$JAVACMD" ]; then
    die "JAVA_HOME is not defined correctly; can not execute: $JAVACMD"
fi

# Increase the maximum file descriptors if we can
if [ "$cygwin" = "false" ]; then
    MAX_FD_LIMIT=`ulimit -H -n`
	if [ "$MAX_FD_LIMIT" != "unlimited" ]; then
	    if [ $? -eq 0 ]; then
	        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then
	            # use the businessSystem max
	            MAX_FD="$MAX_FD_LIMIT"
	        fi

	        ulimit -n $MAX_FD
	        if [ $? -ne 0 ]; then
	            warn "Could not set maximum file descriptor limit: $MAX_FD"
	        fi
	    else
	        warn "Could not query businessSystem maximum file descriptor limit: $MAX_FD_LIMIT"
	    fi
	fi
fi

# Fix the cygwin agent issue
AGENT_GRAILS_HOME=$GRAILS_HOME
if $cygwin ; then
    [ -n "$GRAILS_HOME" ] &&
        AGENT_GRAILS_HOME=`cygpath --windows "$GRAILS_HOME"`
fi

if $mingw ; then
    # Converts GRAILS_HOME path to Windows syntax
    [ -n "$GRAILS_HOME" ] &&
        AGENT_GRAILS_HOME=`cmd //C echo "$GRAILS_HOME"`
fi

if [ -z "$GRAILS_AGENT_CACHE_DIR" ]; then
    GRAILS_AGENT_CACHE_DIR=~/.grails/2.4.4/
fi
SPRINGLOADED_PARAMS=profile=grails\;cacheDir=$GRAILS_AGENT_CACHE_DIR
if [ ! -d "$GRAILS_AGENT_CACHE_DIR" ]; then
    mkdir -p "$GRAILS_AGENT_CACHE_DIR"
fi

# Process JVM args
AGENT_STRING="-javaagent:wrapper/springloaded-1.2.1.RELEASE.jar -Xverify:none -Dspringloaded.synchronize=true -Djdk.reflect.allowGetCallerClass=true -Dspringloaded=$SPRINGLOADED_PARAMS"
CMD_LINE_ARGS=""
DISABLE_RELOADING=true

while true; do
  if [ "$1" = "-cp" ] || [ "$1" = "-classpath" ]; then
    CP=$2
    shift 2
    break
  fi

  if [ "$1" = "-reloading" ]; then
    AGENT=$AGENT_STRING
    DISABLE_RELOADING=false
    shift
    break
  fi

  if [ "$1" = "-noreloading" ]; then
    DISABLE_RELOADING=true
    shift
    break
  fi

  if [ "$1" = "-debug" ]; then
    JAVA_OPTS="$JAVA_OPTS -Xdebug -Xnoagent -Dgrails.full.stacktrace=true -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
    shift
    break
  fi

  if [ "$1" != -* ]; then
    break
  fi

  CMD_LINE_ARGS="$CMD_LINE_ARGS $1"
  shift
done

# Enable agent-based reloading for the 'run-app' command.
if ! $DISABLE_RELOADING; then
    for a in "$@"; do
        if [ "$a" = "run-app" ]; then
            AGENT=$AGENT_STRING
        fi
    done

    if [ $# = 0 ]; then
        AGENT=$AGENT_STRING
    fi
fi

ARGUMENTS="$CMD_LINE_ARGS $@"

# Setup Profiler
useprofiler=false
if [ "x$PROFILER" != "x" ]; then
    if [ -r "$PROFILER" ]; then
        . $PROFILER
        useprofiler=true
    else
        die "Profiler file not found: $PROFILER"
    fi
fi

# For Darwin, use classes.jar for TOOLS_JAR
TOOLS_JAR="$JAVA_HOME/lib/tools.jar"
if $darwin; then
    JAVA_OPTS="-Xdock:name=Grails -Xdock:icon=$GRAILS_HOME/media/icons/grails.icns $JAVA_OPTS"
#   TOOLS_JAR="/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Classes/classes.jar"
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
    GRAILS_HOME=`cygpath --path --mixed "$GRAILS_HOME"`
    JAVA_HOME=`cygpath --path --mixed "$JAVA_HOME"`
    STARTER_CONF=`cygpath --path --mixed "$STARTER_CONF"`
    if [ "x$CP" != "x" ] ; then
        CP=`cygpath --path --mixed "$CP"`
    fi
    TOOLS_JAR=`cygpath --path --mixed "$TOOLS_JAR"`
    STARTER_CLASSPATH=`cygpath --path --mixed "$STARTER_CLASSPATH"`
	# We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW; do
    	ROOTDIRS="$ROOTDIRS$SEP$dir"
	    SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GROOVY_CYGPATTERN" != "" ] ; then
    	OURCYGPATTERN="$OURCYGPATTERN|($GROOVY_CYGPATTERN)"
    fi
    # Now convert the arguments
	ARGUMENTS=""
    for arg in "$@" ; do
    	CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
    	if [ $CHECK -ne 0 ] ; then
	    	convArg=`cygpath --path --ignore --mixed -- "$arg"`
    	else
			convArg=$arg
    	fi
		ARGUMENTS="$ARGUMENTS $convArg"
    done
fi

STARTER_MAIN_CLASS=org.grails.wrapper.GrailsWrapper

lateInit

startGrails() {
  CLASS=$1
  shift
  if [ -n "$GRAILS_OPTS" ]
     then
 	GRAILS_OPTS="$GRAILS_OPTS"
     else
	GRAILS_OPTS="-server -Xmx768M -Xms64M -Dfile.encoding=UTF-8"
	if [ "$GRAILS_NO_PERMGEN" != "1" ]; then
	   GRAILS_OPTS="$GRAILS_OPTS -XX:PermSize=32m -XX:MaxPermSize=256m"
	fi
  fi
  JAVA_OPTS="$GRAILS_OPTS $JAVA_OPTS $AGENT"
  # Start the Profiler or the JVM
  if $useprofiler; then
      runProfiler
  else
  	if [ $# -eq 0 ] ; then         # no argument given
         exec "$JAVACMD" $JAVA_OPTS \
          -classpath "$STARTER_CLASSPATH" \
          -Dgrails.home="$GRAILS_HOME" \
          -Dtools.jar="$TOOLS_JAR" \
          -Djava.net.preferIPv4Stack=true \
          $STARTER_MAIN_CLASS \
          --main $CLASS \
          --conf "$STARTER_CONF" \
          --classpath "$CP"
  	else
         exec "$JAVACMD" $JAVA_OPTS \
          -classpath "$STARTER_CLASSPATH" \
          -Dgrails.home="$GRAILS_HOME" \
          -Dtools.jar="$TOOLS_JAR" \
          -Djava.net.preferIPv4Stack=true \
          $STARTER_MAIN_CLASS \
          --main $CLASS \
          --conf "$STARTER_CONF" \
          --classpath "$CP" \
          "${ARGUMENTS}"
  	fi
  fi
}

startGrails $STARTER_MAIN_CLASS "$@"
